package bitset;

import java.util.Arrays;

public class MyBitSet {
    public byte[] elem;
    //记录当前位图中，存放了多少个有效数据
    public int usedSize;

    /**
     * 默认初始化位为一个字节
     */
    public MyBitSet() {
        this.elem = new byte[1];
    }

    /**
     * 指定构造方法中的初始化位数
     * 一般会多给一个字节，因为如果是12，那么12%8=4，不能整除，还多出来4个bit位
     * 所以多给一个也无所谓(不要那么抠)
     */
    public MyBitSet(int n) {
        this.elem = new byte[n / 8 + 1];
    }

    /**
     * 获取当前位图存储的数据量
     */
    public int getUsedSize() {
        return this.usedSize;
    }


    /**
     * 设置某一位为1(1为有效)
     * @param val
     */
    public void set(int val) {
        if(val < 0) {//必须是大于等于零的整数
            throw new IndexOutOfBoundsException();
        }
        //先确定val在elem的哪一个下标的哪一个bit位
        int arrayIndex = val / 8;
        //扩容
        if(arrayIndex > elem.length - 1) {
            elem = Arrays.copyOf(elem, arrayIndex + 1);
        }
        int bitIndex = val % 8;
        elem[arrayIndex] |= (1 << bitIndex);//不能是异或，会修改原来的值
        usedSize++;
    }

    /**
     * 判断当前位是不是1
     * @param val
     * @return
     */
    public boolean get(int val) {
        if(val < 0) {//必须是大于等于零的整数
            throw new IndexOutOfBoundsException();
        }
        //先确定val在elem的哪一个下标的哪一个bit位
        int arrayIndex = val / 8;
        int bitIndex = val % 8;

        if((elem[arrayIndex] & (1 << bitIndex)) != 0) {
            return true;
        }
        return false;
    }

    /**
     * 将对应位置 设置为0
     * @param val
     */
    public void reSet(int val) {
        if(val < 0) {//必须是大于等于零的整数
            throw new IndexOutOfBoundsException();
        }
        //先确定val在elem的哪一个下标的哪一个bit位
        int arrayIndex = val / 8;
        int bitIndex = val % 8;

        elem[arrayIndex] &= ~(1 << bitIndex);
        usedSize--;
    }

}
